package org.ccg

import consts.AppConstants
import entity.RoomZipBean
import entity.StateBean
import io.ktor.http.*
import io.ktor.http.content.*
import io.ktor.serialization.kotlinx.json.*
import io.ktor.server.application.*
import io.ktor.server.engine.*
import io.ktor.server.http.content.*
import io.ktor.server.netty.*
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.server.plugins.cors.routing.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.utils.io.*
import io.ktor.utils.io.core.readFully
import io.ktor.utils.io.core.remaining
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import kotlin.io.use

fun main() {
    // 启动服务器（新版API更简洁）
    embeddedServer(factory = Netty, port = AppConstants.API_BASE_PORT, module = Application::module).start(wait = true)
}

fun Application.module() {
    install(ContentNegotiation) {
        json()
    }
    // 添加 CORS 支持
    install(CORS) {
        allowMethod(HttpMethod.Options)
        allowMethod(HttpMethod.Put)
        allowMethod(HttpMethod.Delete)
        allowMethod(HttpMethod.Patch)
        allowHeader(HttpHeaders.Authorization)
        allowHeader(HttpHeaders.ContentType)
        // 允许任何域名（仅用于开发环境）
        anyHost()
    }
    // 路由定义
    routing {
        staticResources("/text", "static/text")
        staticFiles("/uploads", File("uploads"))
        /**
         * 获取当前时间
         */
        get("/") {
            val current = LocalDateTime.now()
            call.respondText("WebServer 提示当前时间:     " + current.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
        }
        /**
         * 上传文件
         */
        post("/api/bms/uploadFile") {
            println("/api/bms/uploadFile")
            try {
                val uploadDir = File(AppConstants.FILE_PATH)
                if (!uploadDir.exists()) {
                    uploadDir.mkdirs()
                }
                val multipartData = call.receiveMultipart()
                multipartData.forEachPart { part ->
                    when (part) {
                        is PartData.FileItem -> {
                            val originalFileName = part.originalFileName ?: "unknown"
                            val targetFile = File(uploadDir, originalFileName)
                            try {
                                withContext(Dispatchers.IO) {
                                    val channel = part.provider()
                                    targetFile.outputStream().use { fileOut ->
                                        val buffer = ByteArray(8192)
                                        while (true) {
                                            val packet = channel.readRemaining(buffer.size.toLong())
                                            if (packet.exhausted()) break
                                            val bytes = ByteArray(packet.remaining.toInt())
                                            packet.readFully(bytes)
                                            fileOut.write(bytes)
                                        }
                                    }
                                }
                                call.respond(HttpStatusCode.OK, StateBean(status = 200, msg = "上传文件成功", data = "${AppConstants.API_BASE_URL}/${AppConstants.FILE_PATH}/$originalFileName"))
                            } catch (e: Exception) {
                                targetFile.delete()
                                call.respond(HttpStatusCode.OK, StateBean(status = 201, msg = "保存文件失败: ${e.message}"))
                            }
                        }

                        else -> {
                        }
                    }
                    part.dispose()
                }
            } catch (e: Exception) {
                call.respond(HttpStatusCode.OK, StateBean(status = 202, msg = "上传失败: ${e.localizedMessage}"))
            }
        }
        /**
         * 获取文件夹下所有文件
         */
        get("/api/bms/getAllFile") {
            println("/api/bms/getAllFile")
            val directory = File(AppConstants.FILE_PATH)
            if (!directory.exists()) {
                directory.mkdirs()
            }
            val files = directory.listFiles()
            val fileList = mutableListOf<RoomZipBean>()
            if (files != null) {
                for (file in files) {
                    if (file.isFile) {
                        fileList.add(RoomZipBean(tag = file.nameWithoutExtension, timeStamp = file.lastModified(), roomUrl = "${AppConstants.API_BASE_URL}/${AppConstants.FILE_PATH}/${file.name}"))
                    }
                }
            }
            call.respond(HttpStatusCode.OK, fileList)
        }
    }
}

